package com.yangtzeu.jwc.dao.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;

import com.yangtzeu.jwc.activity.MainActivity;
import com.yangtzeu.jwc.app.MyApplication;
import com.yangtzeu.jwc.business.AppBusiness;
import com.yangtzeu.jwc.businessservice.BusinessHttpCallBack;
import com.yangtzeu.jwc.dao.StudentDao;
import com.yangtzeu.jwc.domain.Course;
import com.yangtzeu.jwc.domain.KbSelection;
import com.yangtzeu.jwc.domain.Sc;
import com.yangtzeu.jwc.domain.Student;
import com.yangtzeu.jwc.domain.XkInfo;
import com.yangtzeu.jwc.utils.ACache;
import com.yangtzeu.jwc.utils.DbUtils;
import com.yangtzeu.jwc.utils.G;
import com.yangtzeu.jwc.utils.UrlParamsUtils;
import com.zjsx.lib.utils.L;
import com.zjsx.lib.utils.StrUtil;

/**
 * 有关用户的操作,需要登录
 *
 * @author ZhangDI
 */
public class StudentDaoImpl extends BasicDaoImpl implements StudentDao {
    private static StudentDao studentDaoImpl = new StudentDaoImpl();

    private StudentDaoImpl() {
        super();
    }

    public static StudentDao getInstance() {
        return studentDaoImpl;
    }

    public void login(final String username, final String password, final String type, final BusinessHttpCallBack callBack) {
        setValidation(G.LOGIN_PATH, new BusinessHttpCallBack() {

            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                if (callBack != null)
                    callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                // 获取验证成功
                // 设置验证以及参数
                clearParams();
                addValidationParams();
                addCustomParams(G.USER_NUMBER, username);
                addCustomParams(G.USER_PASSWORD, password);
                addCustomParams(G.SELKIND, type);
                addCustomParams(G.BTLOGIN, "");
                login(callBack);
            }
        });

    }

    public void login(final BusinessHttpCallBack callBack) {
        doHttpRequest(G.LOGIN_PATH, paramsMap, new BusinessHttpCallBack() {
                    @Override
                    public void onProgress(int bytesWritten, int totalSize) {
                        if (callBack != null)
                            callBack.onProgress(bytesWritten, totalSize);
                    }

                    @Override
                    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                        if (callBack != null)
                            callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
                    }

                    @Override
                    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                        try {
                            Document doc = (Document) obj;
                            Student student = new Student();
                            String userInfo = doc.select("#" + G.LOGIN_USERINFO).text();
                            String[] userinfos = userInfo.split(" ");
                            // 如果得到数据分解成三部分说明登陆成功,封装成学生对象返回
                            if (userinfos.length == 3) {
                                student.setSno(userinfos[0]);
                                student.setSname(userinfos[1]);
                                student.setSclass(userinfos[2]);
                                student.setSpassword(paramsMap.get(G.USER_PASSWORD));
                                MainActivity.student = student;
                                new AppBusiness(MyApplication.getInstance()).login();
                                loginBrodcast();
                                getStudentInfo(null);
                                if (callBack != null)
                                    callBack.onSuccess(responseBody, "登录成功", false, student);
                            } else {
                                if (callBack != null)
                                    callBack.onFailure(responseBody, "用户名或密码错误！", false);
                            }
                        } catch (Exception e) {
                            if (callBack != null)
                                callBack.onFailure(responseBody, "教务处服务器异常！", false);
                        }
                    }
                }

        );
    }

    private void loginBrodcast() {
        Intent itt = new Intent();
        itt.setAction(G.BROADCAST_LOGIN);
        MyApplication.getInstance().sendBroadcast(itt);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.StudentDao#queryBxkJd(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String,
     * com.zhangdi.domain.Student)
     */
    @Override
    public void queryBxkJd(final BusinessHttpCallBack callBack) {
        clearParams();
        addValidationParams();
        addCustomParams(G.EVENTTARGET, "");
        addCustomParams(G.EVENTARGUMENT, "");
        addCustomParams(G.SELYEAR, "" + Calendar.getInstance().get(Calendar.YEAR));
        addCustomParams(G.SELTERM, "1");
        addCustomParams(G.BXKJD, "");
        doHttpRequest(G.INQUERY_SCORE_PATH, paramsMap, new BusinessHttpCallBack() {
            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                try {
                    Document doc = (Document) obj;
                    Elements jd = doc.select("#" + G.JD);
                    String bxkjd = null;
                    if (jd != null)
                        bxkjd = jd.text();
                    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, bxkjd);
                } catch (Exception e) {
                    callBack.onFailure(responseBody, "教务处服务器异常！", false);
                }
            }

        });
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.StudentDao#queryXwkJd(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String,
     * com.zhangdi.domain.Student)
     */
    @Override
    public void queryXwkJd(final BusinessHttpCallBack callBack) {

        // 得到验证后继续发送查询成绩的参数和验证
        clearParams();
        addValidationParams();
        addCustomParams(G.EVENTTARGET, "");
        addCustomParams(G.EVENTARGUMENT, "");
        addCustomParams(G.SELYEAR, "" + Calendar.getInstance().get(Calendar.YEAR));
        addCustomParams(G.SELTERM, "1");
        addCustomParams(G.XWKJD, "");
        doHttpRequest(G.INQUERY_SCORE_PATH, paramsMap, new BusinessHttpCallBack() {

            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                try {
                    Document doc = (Document) obj;
                    Elements jd = doc.select("#" + G.JD);
                    String xwkJd = null;
                    if (jd != null)
                        xwkJd = jd.text();
                    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, xwkJd);
                } catch (Exception e) {
                    callBack.onFailure(responseBody, "教务处服务器异常！", false);
                }
            }

        });
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.StudentDao#queryScore(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String,
     * com.zhangdi.domain.Student)
     */
    @Override
    public void queryScore(final boolean fromCache, final BusinessHttpCallBack callBack) {
        String url = G.INQUERY_SCORE_PATH;
        setValidation(url, new BusinessHttpCallBack() {

            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                try {
                    clearParams();
                    addValidationParams();
                    addCustomParams(G.EVENTTARGET, G.QUERYALLSCORE);
                    addCustomParams(G.EVENTARGUMENT, "");
                    addCustomParams(G.SELYEAR, Calendar.getInstance().get(Calendar.YEAR) + "");
                    addCustomParams(G.SELTERM, "1");
                    queryScore2(fromCache, callBack);
                } catch (Exception e) {
                    callBack.onFailure(responseBody, "教务处服务器异常！", false);
                }
            }

        });
    }

    // 解析网页中的成绩
    public List<Sc> queryScoreFromDoc(Document doc) {
        List<Sc> scores = new ArrayList<Sc>();
        // 得到显示分数的表格
        Elements table = doc.select("#" + G.SCORE_TABLE);
        // 得到每一行数据
        Elements trs = table.select("tr");
        Sc sc;
        // 循环取出成绩数据,并存放到List中
        for (int i = 1; i < trs.size(); i++) {
            String[] tdvalues = trs.get(i).text().split(" ");
            if (tdvalues.length == 6) {
                sc = new Sc(MainActivity.student.getSno(), tdvalues[0], tdvalues[2], tdvalues[3], tdvalues[4], tdvalues[5], tdvalues[1]);
                scores.add(sc);
            }
        }
        return scores;
    }

    public void queryScore2(final boolean fromCache, final BusinessHttpCallBack callBack) {
        String url = G.INQUERY_SCORE_PATH;
        final String cacheName = url + paramsMap.toString();
        String docStr = aCache.getAsString(cacheName);

        if (docStr != null && fromCache) {
            List<Sc> scores = queryScoreFromDoc(Jsoup.parse(docStr));
            callBack.onSuccess(null, null, false, scores);
        }
        doHttpRequest(url, paramsMap, new BusinessHttpCallBack() {

            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                try {
                    List<Sc> scores = queryScoreFromDoc((Document) obj);
                    aCache.put(cacheName, obj.toString(), ACache.TIME_MONTH);
                    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, scores);
                } catch (Exception e) {
                    callBack.onFailure(responseBody, "教务处服务器异常！", false);
                }
            }
        });
    }

    // 通过web页面获得学生信息
    public void getStudentInfoFromDoc(Document doc) throws Exception {
        try {
            // 学生性别
            String ssex = doc.select(G.USER_SEX_ID).text();
            // 学生身份证号
            String sjid = doc.select(G.USER_SJID_ID).val();
            // 学生头像地址
            String sphoto = G.JWC_HOME + doc.select(G.USER_PHOTO_ID).attr("src");

            MainActivity.student.setSsex(ssex);
            MainActivity.student.setSjid(sjid);
            MainActivity.student.setSphoto(sphoto);
            MainActivity.student.type = "info";
            loginBrodcast();

        } catch (Exception e) {
            throw e;
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.zhangdi.dao.impl.StudentDao#getStudentInfo(com.zhangdi.domain.Student
     * )
     */
    @Override
    public void getStudentInfo(final BusinessHttpCallBack callBack) {
        String url = G.USER_INFO_PATH_CET;
        final String cacheName = url;
        String docStr = aCache.getAsString(cacheName);
        if (docStr != null) {
            try {
                getStudentInfoFromDoc(Jsoup.parse(docStr));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        doHttpRequest(G.USER_INFO_PATH_CET, new BusinessHttpCallBack() {

            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                if (callBack != null)
                    callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                if (callBack != null)
                    callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                try {
                    getStudentInfoFromDoc((Document) obj);
                    if (callBack != null)
                        callBack.onSuccess(responseBody, successMsg, isNoticeDialog, obj);
                    aCache.put(cacheName, obj.toString(), ACache.TIME_MONTH);
                } catch (Exception e) {
                    callBack.onFailure(responseBody, "教务处服务器异常！", false);
                }
            }

        });
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.StudentDao#saveStudent(android.content.Context,
     * java.lang.String, java.lang.String)
     */
    @Override
    public void saveStudent(Context context, String name, String password) {

        DbUtils db = null;
        try {
            db = new DbUtils(context);
            db.getWritableDatabase().execSQL("insert into student(name,password) values(?,?)", new String[]{name, password});
            db.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (db != null)
                db.close();
        }
    }

    @Override
    public void modifySavedStudent(Context context, String name, String password) {

        DbUtils db = null;
        try {
            db = new DbUtils(context);
            db.getWritableDatabase().execSQL("update student set password = ? where name = ?", new String[]{password, name});
            db.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (db != null)
                db.close();
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.zhangdi.dao.impl.StudentDao#getSavedStudent(android.content.Context)
     */
    @Override
    public Student getSavedStudent(Context context) {
        DbUtils db = null;
        Student student = null;
        try {
            db = new DbUtils(context);
            Cursor cursor = db.getWritableDatabase().rawQuery("select name,password from student", new String[]{});
            if (cursor.moveToFirst()) {
                String name = cursor.getString(cursor.getColumnIndex("name"));
                String password = cursor.getString(cursor.getColumnIndex("password"));
                student = new Student();
                student.setSno(name);
                student.setSpassword(password);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            db.close();
        }
        return student;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.zhangdi.dao.impl.StudentDao#clearStudent(android.content.Context)
     */
    @Override
    public void clearStudent(Context context) {
        DbUtils db = null;
        try {
            db = new DbUtils(context);
            db.getWritableDatabase().execSQL("delete from student");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (db != null)
                db.close();
        }
    }

    /**
     * 查看选课信息
     */
    @Override
    public void getXkInfo(final BusinessHttpCallBack callBack) {
        doHttpRequest(G.XKINFO, new BusinessHttpCallBack() {

            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                try {
                    Document doc = (Document) obj;
                    XkInfo info = new XkInfo();
                    String lbGxMax = "lbGxMax";
                    info.setLbGxMax(doc.select("#" + lbGxMax).text());
                    String lbZyMax = "lbZyMax";
                    info.setLbZyMax(doc.select("#" + lbZyMax).text());
                    String lbGxxf = "lbGxxf";
                    info.setLbGxxf(doc.select("#" + lbGxxf).text());
                    String lbGxbjgxf = "lbGxbjgxf";
                    info.setLbGxbjgxf(doc.select("#" + lbGxbjgxf).text());
                    String lbGx = "lbGx";
                    info.setLbGx(doc.select("#" + lbGx).text());
                    String lbGxCount = "lbGxCount";
                    info.setLbGxCount(doc.select("#" + lbGxCount).text());
                    String lbGxMaxCount = "lbGxMaxCount";
                    info.setLbGxMaxCount(doc.select("#" + lbGxMaxCount).text());
                    String lbZyxf = "lbZyxf";
                    info.setLbZyxf(doc.select("#" + lbZyxf).text());
                    String lbZybjgxf = "lbZybjgxf";
                    info.setLbZybjgxf(doc.select("#" + lbZybjgxf).text());
                    String lbZy = "lbZy";
                    info.setLbZy(doc.select("#" + lbZy).text());

                    // 年份信息和选课的年份以及学期
                    Elements year_opts = doc.select("#" + G.SELYEAR).select("option");
                    Element year_opt = null;
                    String[] years = new String[year_opts.size()];
                    for (int i = 0; i < year_opts.size(); i++) {
                        year_opt = year_opts.get(i);
                        if ("selected".equals(year_opt.attributes().get("selected"))) {
                            info.setSelectedYear(year_opt.text());
                        }
                        years[i] = year_opt.text();
                    }
                    info.setYears(years);
                    year_opt = null;
                    year_opts = null;

                    // 校区
                    Elements xiaoqo_opts = doc.select("#selXiaoqu").select("option");
                    Element xiaoqo_opt = null;
                    String[] xiaoqus = new String[xiaoqo_opts.size()];
                    for (int i = 0; i < xiaoqo_opts.size(); i++) {
                        xiaoqo_opt = xiaoqo_opts.get(i);
                        if ("selected".equals(xiaoqo_opt.attributes().get("selected"))) {
                            info.setSelectedXiaoqu(xiaoqo_opt.text());
                        }
                        xiaoqus[i] = xiaoqo_opt.text();
                        ;
                    }

                    info.setXiqoqus(xiaoqus);
                    xiaoqo_opts = null;
                    xiaoqo_opt = null;

                    // 选课的学期
                    Elements term_opts = doc.select("#" + G.SELTERM).select("option");
                    Element term_opt = null;
                    String[] terms = new String[term_opts.size()];
                    for (int i = 0; i < term_opts.size(); i++) {
                        term_opt = term_opts.get(i);
                        if ("selected".equals(term_opt.attributes().get("selected"))) {
                            info.setSelectedTerms(term_opt.val());
                        }
                        terms[i] = term_opt.val();
                    }
                    info.setTerms(terms);
                    term_opt = null;
                    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, info);
                } catch (Exception e) {
                    callBack.onFailure(responseBody, "教务处服务器异常！", false);
                }
            }
        });
    }

    /**
     * 获取已选课程
     */
    @Override
    public void getXkInfo(String selYear, String selTerm, String selXiaoqu, final BusinessHttpCallBack callBack) {
        clearParams();
        addValidationParams();
        addCustomParams(G.EVENTTARGET, "btQuery");
        addCustomParams(G.EVENTARGUMENT, "");
        addCustomParams(G.VIEWSTATE, viewstate);
        addCustomParams(G.EVENTVALIDATION, eventvalidation);
        addCustomParams(G.SELYEAR, selYear);
        addCustomParams(G.SELTERM, selTerm);
        addCustomParams("selXiaoqu", selXiaoqu);

        doHttpRequest(G.XKINFO, paramsMap, new BusinessHttpCallBack() {
            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                try {
                    Document doc = (Document) obj;
                    // L.d(doc.toString());
                    Elements tables = doc.select("table");
                    Element table = tables.get(tables.size() - 1);
                    // L.d(table.text());
                    Elements trs = table.select("tr");
                    // L.d(trs.size());
                    Element tr = null;
                    Elements tds = null;
                    Element td = null;
                    List<Course> courses = new LinkedList<Course>();
                    Course course = null;
                    for (int i = 1; i < trs.size() - 1; i++) {
                        course = new Course();
                        tr = trs.get(i);
                        tds = tr.select("td");
                        // 地零个得到是否可选
                        String input = tds.get(0).select("input").toString();
                        boolean noDelete = (input == null || "".equalsIgnoreCase(input.trim()));
                        if (noDelete || "disabled".equalsIgnoreCase(tds.get(0).select("input").attr("disabled"))) {
                            course.setCanSelect(false);
                        } else {
                            course.setCanSelect(true);
                        }
                        // 第一个列含有链接
                        td = tds.get(1);
                        Elements es = td.select("a");
                        // L.d(es.size());
                        Element e = es.get(0);
                        e.attributes().get("href");
                        // 获取课程的链接信息
                        String courseUrl = td.select("a").get(0).attributes().get("href");
                        // 从链接中解析出链接中包含的课程编号
                        String courseId = UrlParamsUtils.getParams(courseUrl).get("no");
                        course.setId(courseId);
                        // L.d(courseId);

                        // 将每门选修课的信息迭代到一个数组中
                        String[] courseInfo = new String[tds.size() - 1];
                        for (int j = 1; j < tds.size(); j++) {
                            courseInfo[j - 1] = tds.get(j).text();
                        }
                        // L.d(tds.size() + "--------");
                        // 从数组中取出课程信息,并放到课程对象中.
                        course.setCname(courseInfo[0]);
                        course.setCredit(courseInfo[1]);
                        course.setTime(courseInfo[2]);
                        // course.setMaxCount(courseInfo[3]);
                        // course.setCount(courseInfo[4]);
                        course.setTeacher(courseInfo[3]);
                        course.setClass1(courseInfo[4]);
                        course.setType(courseInfo[5]);

                        courses.add(course);
                    }
                    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, courses);
                } catch (Exception e) {
                    callBack.onFailure(responseBody, "教务处服务器异常！", false);
                }
            }
        });
    }

    @Override
    public void getGxk(final String xiaoqu, final BusinessHttpCallBack callBack) {
        // 首先更新一下验证码
        getXkInfo(new BusinessHttpCallBack() {

            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                getGxkList((XkInfo) obj, xiaoqu, callBack);
            }

        });
    }

    public void getGxkList(final XkInfo info, final String Xiaoqu, final BusinessHttpCallBack callBack) {
        clearParams();
        addValidationParams();
        addCustomParams(G.EVENTTARGET, "btAddgx");
        addCustomParams(G.EVENTARGUMENT, "");
        addCustomParams(G.VIEWSTATE, viewstate);
        addCustomParams(G.EVENTVALIDATION, eventvalidation);
        addCustomParams(G.SELYEAR, "2014");
        addCustomParams(G.SELTERM, "2");
        addCustomParams("selXiaoqu", Xiaoqu);
        doHttpRequest(G.XKINFO, paramsMap, new BusinessHttpCallBack() {
            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                try {
                    Document doc = (Document) obj;
                    // L.d(doc.toString());
                    Elements tables = doc.select("table");
                    Element table = tables.get(tables.size() - 1);
                    // L.d(table.text());
                    Elements trs = table.select("tr");
                    // L.d(trs.size());
                    Element tr = null;
                    Elements tds = null;
                    Element td = null;
                    List<Course> courses = new ArrayList<Course>();
                    Map GxkInfo = new HashMap();
                    Course course = null;
                    for (int i = 1; i < trs.size() - 1; i++) {
                        course = new Course();
                        tr = trs.get(i);
                        tds = tr.select("td");
                        // 地零个得到是否可选
                        if ("disabled".equalsIgnoreCase(tds.get(0).select("input").attr("disabled"))) {
                            course.setCanSelect(false);
                        } else {
                            course.setCanSelect(true);
                        }
                        // 第一个列含有链接
                        td = tds.get(1);
                        Elements es = td.select("a");
                        // L.d(es.size());
                        Element e = es.get(0);
                        e.attributes().get("href");
                        // 获取课程的链接信息
                        String courseUrl = td.select("a").get(0).attributes().get("href");
                        // 从链接中解析出链接中包含的课程编号
                        String courseId = UrlParamsUtils.getParams(courseUrl).get("no");
                        course.setId(courseId);
                        // L.d(courseId);

                        // 将每门选修课的信息迭代到一个数组中
                        String[] courseInfo = new String[tds.size() - 1];
                        for (int j = 1; j < tds.size(); j++) {
                            courseInfo[j - 1] = tds.get(j).text();
                        }
                        // L.d(tds.size() + "--------");
                        // 从数组中取出课程信息,并放到课程对象中.
                        course.setCname(courseInfo[0]);
                        course.setCredit(courseInfo[1]);
                        course.setTime(courseInfo[2]);
                        course.setMaxCount(courseInfo[3]);
                        course.setCount(courseInfo[4]);
                        // course.setTeacher(courseInfo[3]);
                        course.setClass1(courseInfo[5]);
                        course.setType(courseInfo[6]);
                        courses.add(course);
                    }
                    GxkInfo.put("xkInfo", info);
                    GxkInfo.put("gxkList", courses);
                    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, GxkInfo);
                } catch (Exception e) {
                    callBack.onFailure(responseBody, "教务处服务器异常！", false);
                }
            }

        });
    }

    @Override
    public void xxGxk(String courseId, final BusinessHttpCallBack callBack) {
        String add = G.JWC_HOME + "/Xk2.aspx?rwh=" + courseId + "&action=1";
        doHttpRequest(add, new BusinessHttpCallBack() {

            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                try {
                    Document doc = (Document) obj;
                    String resuleMsg = doc.toString();
                    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, resuleMsg);
                } catch (Exception e) {
                    callBack.onFailure(responseBody, "教务处服务器异常！", false);
                }
            }

        });
    }

    @Override
    public void qxxxGxk(Student student, String courseId, final BusinessHttpCallBack callBack) {
        String delete = G.JWC_HOME + "/Xk2.aspx?rwh=" + courseId + "&action=2";
        doHttpRequest(delete, new BusinessHttpCallBack() {

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                Document doc = (Document) obj;
                String data = doc.toString();
                if (data.contains("删除成功")) {
                    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, obj);
                } else {
                    callBack.onFailure(responseBody, "删除失败，请尝试在网页上操作！", isNoticeDialog);
                }
            }

        });
    }

    public void changePassword(final String newPassword, final BusinessHttpCallBack callBack) {
        String path = G.CHANGE_PASSWORD;
        doHttpRequest(path, new BusinessHttpCallBack() {

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                clearParams();
                addValidationParams();
                addCustomParams("OldPwd", MainActivity.student.getSpassword());
                addCustomParams("ps2", newPassword);
                addCustomParams("btOK", "ȷ��");
                changePassword(callBack);
            }

        });
    }

    public void changePassword(final BusinessHttpCallBack callBack) {
        String path = G.CHANGE_PASSWORD;
        doHttpRequest(path, paramsMap, new BusinessHttpCallBack() {
            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                Document doc = (Document) obj;
                String data = doc.toString();
                if (data.contains("密码修改成功")) {
                    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, obj);
                } else {
                    callBack.onFailure(responseBody, doc.toString(), isNoticeDialog);
                }
            }

        });
    }

    public boolean getKbSelectionFromDoc(Document doc, BusinessHttpCallBack callBack) {
        KbSelection kbSelection = new KbSelection();
        // 选课的学期
        Map<String, String> terms = new LinkedHashMap<String, String>();
        Elements term_opts = doc.select("#" + G.SELTERM).select("option");
        Element term_opt = null;
        for (int i = 0; i < term_opts.size(); i++) {
            term_opt = term_opts.get(i);
            terms.put(term_opt.text(), term_opt.val());
            if ("selected".equals(term_opt.attributes().get("selected"))) {
                kbSelection.setSelectedTerm(term_opt.text());
            }
        }
        kbSelection.setTerms(terms);
        term_opt = null;
        term_opts = null;
        // 年份信息和选课的年份以及学期
        Elements year_opts = doc.select("#" + G.SELYEAR).select("option");
        Element year_opt = null;
        Map<String, String> years = new LinkedHashMap<String, String>();
        for (int i = 0; i < year_opts.size(); i++) {
            year_opt = year_opts.get(i);
            years.put(year_opt.text(), year_opt.val());
            if ("selected".equals(year_opt.attributes().get("selected"))) {
                kbSelection.setSelectedYear(year_opt.text());
            }
        }
        kbSelection.setYears(years);
        year_opt = null;
        year_opts = null;
        // 获取课表类别
        Elements kblb_opts = doc.select("#" + G.SELKBLB).select("option");
        Element kblb_opt = null;
        Map<String, String> kblbs = new LinkedHashMap<String, String>();
        for (int i = 0; i < kblb_opts.size(); i++) {
            kblb_opt = kblb_opts.get(i);
            kblbs.put(kblb_opt.text(), kblb_opt.val());
        }
        kbSelection.setKblbs(kblbs);
        kblb_opt = null;
        kblb_opts = null;
        // 获取部门
        Elements dept_opts = doc.select("#" + G.SELDEPART).select("option");
        Element dept_opt = null;
        Map<String, String> depts = new LinkedHashMap<String, String>();
        for (int i = 0; i < dept_opts.size(); i++) {
            dept_opt = dept_opts.get(i);
            if (!StrUtil.isEmpty((dept_opt.text()))) {
                depts.put(dept_opt.text(), dept_opt.val());
            }
        }
        kbSelection.setDepts(depts);
        dept_opt = null;
        dept_opts = null;
        return getClassByDoc(doc, kbSelection, callBack);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.JwcDao#getKbSelection()
     */
    @Override
    public void getKbSelection(final BusinessHttpCallBack callBack) {
        doHttpRequest(G.KB_PATH, new BusinessHttpCallBack() {

            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                try {
                    getKbSelectionFromDoc((Document) obj, callBack);
                } catch (Exception e) {
                    callBack.onFailure(responseBody, "教务处服务器异常！", false);
                }
            }
        });

    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.JwcDao#queryClass(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public void queryClass(String selYear, String selTerm, String selDepart, String selClass, final BusinessHttpCallBack callBack) {
        clearParams();
        addValidationParams();
        addCustomParams(G.EVENTTARGET, G.SELDEPART);
        addCustomParams(G.EVENTARGUMENT, "");
        addCustomParams(G.LASTFOCUS, "");
        addCustomParams(G.VIEWSTATE, viewstate);
        addCustomParams(G.EVENTVALIDATION, eventvalidation);
        addCustomParams(G.SELYEAR, selYear);
        addCustomParams(G.SELTERM, selTerm);
        addCustomParams(G.SELKBLB, 1 + "");
        addCustomParams(G.SELDEPART, selDepart);
        addCustomParams(G.SELCLASS, selClass);
        String url = G.KB_PATH;
        final String cacheName = url + paramsMap.toString();
        String docStr = aCache.getAsString(cacheName);

        if (docStr != null) {
            boolean isParseOk = getClassByDoc(Jsoup.parse(docStr), null, callBack);
            if (isParseOk) {
                return;
            }
        }
        doHttpRequest(G.KB_PATH, paramsMap, new BusinessHttpCallBack() {
            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                Document doc = (Document) obj;
                aCache.put(cacheName, doc.toString(), ACache.TIME_MONTH);
                getClassByDoc(doc, null, callBack);
            }
        });
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.JwcDao#getClassByDoc(org.jsoup.nodes.Document)
     */
    @Override
    public boolean getClassByDoc(Document doc, KbSelection kbSelection, BusinessHttpCallBack callBack) {
        try {
            Elements class_opts = doc.select("#" + G.SELCLASS).select("option");
            Element class_opt = null;
            Map<String, String> classes = new LinkedHashMap<String, String>();
            for (int i = 0; i < class_opts.size(); i++) {
                class_opt = class_opts.get(i);
                classes.put(class_opt.text(), class_opt.val());
            }
            class_opt = null;
            class_opts = null;
            if (kbSelection != null) {
                kbSelection.setClasses(classes);
                callBack.onSuccess(null, null, false, kbSelection);
            } else {
                callBack.onSuccess(null, null, false, classes);
            }
            return true;
        } catch (Exception e) {
            callBack.onFailure(null, "教务处服务器异常！", false);
            return false;
        }
    }

    public String[][] queryKbFromDoc(Document doc) {
        String[][] kebiao = null;
        Elements trs = doc.select("#" + G.DGKB).select("tr");
        Element tr = null;
        Elements tds = null;
        Element td = null;
        kebiao = new String[trs.size() - 1][7];
        // 得到表格,拆分后放到数组返回.
        for (int i = 1; i < trs.size(); i++) {
            tr = trs.get(i);
            tds = tr.select("td");
            for (int j = 1; j < tds.size(); j++) {
                td = tds.get(j);
                kebiao[i - 1][j - 1] = td.text();
            }
        }
        trs = null;
        tr = null;
        tds = null;
        td = null;
        L.d("课表" + kebiao[0][0] + kebiao[0][1]);
        return kebiao;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.JwcDao#queryKb(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public void queryKb(String selYear, String selTerm, String selDepart, String selClass, final BusinessHttpCallBack callBack) {
        clearParams();
        addValidationParams();
        addCustomParams(G.EVENTTARGET, G.BTQUERY);
        addCustomParams(G.EVENTARGUMENT, "");
        addCustomParams(G.LASTFOCUS, "");
        addCustomParams(G.VIEWSTATE, viewstate);
        addCustomParams(G.EVENTVALIDATION, eventvalidation);
        addCustomParams(G.SELYEAR, selYear);
        addCustomParams(G.SELTERM, selTerm);
        addCustomParams(G.SELKBLB, 1 + "");
        addCustomParams(G.SELDEPART, selDepart);
        addCustomParams(G.SELCLASS, selClass);
        String url = G.KB_PATH;
        final String cacheName = url + paramsMap.toString();
        String docStr = aCache.getAsString(cacheName);
        if (docStr != null) {
            String[][] kebiao = queryKbFromDoc(Jsoup.parse(docStr));
            callBack.onSuccess(null, null, false, kebiao);
            if (kebiao != null && kebiao.length != 0)
                return;
        }
        doHttpRequest(url, paramsMap, new BusinessHttpCallBack() {
            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                callBack.onProgress(bytesWritten, totalSize);
            }

            @Override
            public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
                callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
            }

            @Override
            public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
                try {
                    Document doc = (Document) obj;
                    String[][] kebiao = queryKbFromDoc(doc);
                    aCache.put(cacheName, doc.toString(), ACache.TIME_MONTH);
                    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, kebiao);
                } catch (Exception e) {
                    callBack.onFailure(responseBody, "教务处服务器异常！", false);
                }
            }

        });
    }
}
